﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Globalization;

namespace GoogleMaps
{
	/// <summary>
	/// A polyline that will be drawn on the map using the facilities of the browser or an image overlay. 
	/// Somve browsers support the ability to draw vector graphics on images.
	/// </summary>
	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Polyline")]
	public class GPolyline
	{
		/// <summary>
		/// Initializes a new instance of the GPolyline class.
		/// </summary>
		public GPolyline()
		{
			GEvents = new GEventCollection();
			GLatLngs = new GLatLngCollection();

			Clickable = true;
		}

		/// <summary>
		/// Renders the control by appending it to the stringbuilder that contains the JavaScript 
		/// for the related Google Map.
		/// </summary>
		/// <param name="js">A string builder containing the javascript that goes with the Google Map.</param>
		/// <param name="javaScriptVariableName">The namve of the JavaScript variable that is holding the map.</param>
		public void Render(StringBuilder js, string javaScriptVariableName)
		{
			string options = "";

			if (!Clickable)
				options = "clickable:false";

			if (Geodesic)
				options = String.Format(CultureInfo.InvariantCulture, "{0}{1}geodesic:true", options, (options.Length > 0) ? "," : "");

			if (options.Length > 0)
				options = String.Format(CultureInfo.InvariantCulture, ", {{{0}}}", options);

			if ((GEvents == null || GEvents.Count == 0) && String.IsNullOrEmpty(Id))
			{
				js.AppendFormat(CultureInfo.InvariantCulture, "{0}.addOverlay(new GPolyline({1}, \"{2}\", {3}, {4}{5}));", javaScriptVariableName,
					GLatLngs.ToJavaScriptArray(), Color, Weight.ToString(CultureInfo.InvariantCulture),
					Opacity.HasValue ? Opacity.Value.ToString(CultureInfo.InvariantCulture) : "null", options);
			}
			else
			{
				if (String.IsNullOrEmpty(Id))
					throw new InvalidOperationException(Properties.Resources.GMarkerIdRequired);

				js.AppendFormat(CultureInfo.InvariantCulture, "var {0} = new GPolyline({1}, \"{2}\", {3}, {4}{5});", Id,
					GLatLngs.ToJavaScriptArray(), Color, Weight.ToString(CultureInfo.InvariantCulture),
					Opacity.HasValue ? Opacity.Value.ToString(CultureInfo.InvariantCulture) : "null", options);

				if (GEvents != null)
					foreach (GEvent ge in GEvents)
						ge.Render(js, Id);

				js.AppendFormat(CultureInfo.InvariantCulture, "{0}.addOverlay({1});", javaScriptVariableName, Id);
			}
		}

		/// <summary>
		/// Gets or sets the javascirpt id that is to be used when this polyline is created.
		/// </summary>
		public string Id { get; set; }

		/// <summary>
		/// Gets or sets a flag indicating that this polyline is clickable.
		/// </summary>
		public bool Clickable { get; set; }

		/// <summary>
		/// Gets or sets a flag indicating that this polyline will curve to represent the shortes distance
		/// between the two point along the curvature of the earth.
		/// </summary>
		public bool Geodesic { get; set; }

		/// <summary>
		/// Gets a collection of events that are wired up to the map.
		/// </summary>
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public GEventCollection GEvents { get; private set; }

		/// <summary>
		/// Gets a collection of GLatLng coordicates that are used to create the polyline.
		/// </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Lngs"), 
		PersistenceMode(PersistenceMode.InnerProperty)]
		public GLatLngCollection GLatLngs { get; private set; }

		/// <summary>
		/// Gets or sets the color of the polyline
		/// </summary>
		public string Color { get; set; }

		/// <summary>
		/// Gets or sets the width of the poyline as a unit of pixels.
		/// </summary>
		public int Weight { get; set; }

		/// <summary>
		/// Gets or sets level of opacity that the polyline will have (1.0 is opaque and 0.0 is transparent).
		/// </summary>
		public decimal? Opacity { get; set; }
	}
}
